package com.shijunhao.graduation.service.system.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shijunhao.graduation.domain.entity.BaseEntity;
import com.shijunhao.graduation.domain.entity.SystemDict;
import com.shijunhao.graduation.domain.entity.SystemDictItem;
import com.shijunhao.graduation.mapper.SystemDictMapper;
import com.shijunhao.graduation.service.system.ISystemDictItemService;
import com.shijunhao.graduation.service.system.ISystemDictService;
import com.shijunhao.graduation.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author shijunhao
 * @since 2022-03-04
 */
@Service
public class SystemDictServiceImpl extends BaseServiceImpl<SystemDictMapper, SystemDict> implements ISystemDictService {

    private final ISystemDictItemService systemDictItemService;

    private static final String REDIS_DICT_KEY = "system:dict:";

    @Autowired
    public SystemDictServiceImpl(ISystemDictItemService systemDictItemService) {
        this.systemDictItemService = systemDictItemService;
    }

    @Override
    public SystemDict loadByCode(String code) {
        String key = REDIS_DICT_KEY +"code:"+ code;
        if(RedisUtils.hasKey(key)){
            return RedisUtils.get(key, SystemDict.class);
        }
        SystemDict result = getOne(Wrappers.lambdaQuery(SystemDict.class).eq(SystemDict::getCode, code));
        if(result == null)
            return null;
        List<SystemDictItem> items = systemDictItemService.loadByDictId(result.getId());
        result.setDictItems(items);
        RedisUtils.set(key,result);
        return result;
    }

    @Override
    public SystemDictItem loadByCodeLabel(String code, String label) {
        String key = REDIS_DICT_KEY +"codeLabel:"+ code+":"+label;
        if(RedisUtils.hasKey(key)){
            return RedisUtils.get(key, SystemDictItem.class);
        }
        SystemDict dict = getOne(Wrappers.lambdaQuery(SystemDict.class).eq(SystemDict::getCode, code));
        if(dict == null)
            return null;
        SystemDictItem result = systemDictItemService.loadByDictIdLabel(dict.getId(), label);
        RedisUtils.set(key,result);
        return result;
    }

    @Override
    public SystemDictItem loadByCodeValue(String code, Integer value) {
        String key = REDIS_DICT_KEY +"codeValue:"+ code+":"+value;
        if(RedisUtils.hasKey(key)){
            return RedisUtils.get(key, SystemDictItem.class);
        }
        SystemDict dict = getOne(Wrappers.lambdaQuery(SystemDict.class).eq(SystemDict::getCode, code));
        if(dict == null)
            return null;
        SystemDictItem result = systemDictItemService.loadByDictIdValue(dict.getId(), value);
        RedisUtils.set(key,result);
        return result;
    }

    @Override
    public SystemDict getById(Long id) {
        String key = REDIS_DICT_KEY+id;
        if(RedisUtils.hasKey(key)){
            return RedisUtils.get(key, SystemDict.class);
        }
        SystemDict dict = super.getById(id);
        if(dict == null)
            return null;
        dict.setDictItems(systemDictItemService.loadByDictId(dict.getId()));
        RedisUtils.set(key,dict);
        return dict;
    }

    @Override
    public List<SystemDict> listByIds(Collection<Long> ids) {
        List<SystemDict> dicts = super.listByIds(ids);
        fillDictItems(dicts);
        return dicts;
    }

    @Override
    public List<SystemDict> selectByCondition(Wrapper<SystemDict> wrapper) {
        List<SystemDict> dicts = super.selectByCondition(wrapper);
        fillDictItems(dicts);
        return dicts;
    }

    @Override
    public List<SystemDict> listByCondition(Wrapper<SystemDict> wrapper) {
        List<SystemDict> dicts = super.listByCondition(wrapper);
        fillDictItems(dicts);
        return dicts;
    }

    @Override
    public Page<SystemDict> page(IPage<SystemDict> page, Wrapper<SystemDict> wrapper) {
        Page<SystemDict> pageInfo = super.page(page, wrapper);
        fillDictItems(pageInfo.getRecords());
        return pageInfo;
    }

    @Override
    public Page<SystemDict> page(IPage<SystemDict> page) {
        Page<SystemDict> pageInfo = super.page(page);
        fillDictItems(pageInfo.getRecords());
        return pageInfo;
    }

    @Override
    public SystemDict getOne(Wrapper<SystemDict> wrapper) {
        SystemDict dict = super.getOne(wrapper);
        if(dict == null)
            return null;
        dict.setDictItems(systemDictItemService.loadByDictId(dict.getId()));
        return dict;
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Long id) {
        systemDictItemService.deleteByDictId(id);
        super.deleteById(id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIds(Collection<Long> ids) {
        systemDictItemService.deleteByDictIds(ids);
        super.deleteByIds(ids);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByCondition(Wrapper<SystemDict> wrapper) {
        List<SystemDict> dicts = selectByCondition(wrapper);
        List<Long> dictIds = dicts.stream().map(BaseEntity::getId).collect(Collectors.toList());
        systemDictItemService.deleteByDictIds(dictIds);
        super.deleteByIds(dictIds);
        return true;
    }

    private void fillDictItems(Collection<SystemDict> dicts){
        for(SystemDict dict:dicts){
            List<SystemDictItem> items = systemDictItemService.loadByDictId(dict.getId());
            dict.setDictItems(items);
        }
    }
}
